package online.exam.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpStatus;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import online.exam.common.YesOrNo;
import online.exam.mapper.AnswerPaperMapper;
import online.exam.mapper.SubjectBankMapper;
import online.exam.mapper.TestPaperMapper;
import online.exam.pojo.AnswerPaper;
import online.exam.pojo.SubjectBank;
import online.exam.pojo.TestPaper;
import online.exam.pojo.vo.DoTestPaperVO;
import online.exam.pojo.vo.TestPaperVO;
import online.exam.pojo.vo.TestSubjectsVO;
import online.exam.service.TestService;
import online.exam.utils.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;

/**
 * @author 王景煜
 */

@Service
public class TestServiceImpl implements TestService {

    @Autowired
    private TestPaperMapper testPaperMapper;

    @Autowired
    private SubjectBankMapper subjectBankMapper;

    @Autowired
    private AnswerPaperMapper answerPaperMapper;

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PageUtils<TestPaperVO> queryAllTestPaper(Integer page, Integer limit, String clazz) {
        Map<String, Object> map = new HashMap<>();
        if (!StringUtils.isEmpty(clazz))
            map.put("clazz", clazz);
        PageHelper.startPage(page, limit);
        List<TestPaperVO> paperList = testPaperMapper.selectAllTestPaper(map);
        PageInfo<?> tpInfo = new PageInfo<>(paperList);
        PageUtils<TestPaperVO> pageUtils = new PageUtils<>();
        pageUtils.setPage(page);
        pageUtils.setLimit(limit);
        pageUtils.setCount(tpInfo.getTotal());
        pageUtils.setData(paperList);
        return pageUtils;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public int addTestPaper(List<SubjectBank> bankList, List<TestPaper> tpList) {

        int sbResult = 0, tpResult = 0;
        // 试卷编号
        String testId = IdUtil.simpleUUID();
        // 创建时间
        Date createTime = new Date();

        for (int i = 0; i < bankList.size(); i++) {
            SubjectBank sb = bankList.get(i);
            TestPaper tp = tpList.get(i);

            // 每道题的编号
            String subjectId = IdUtil.simpleUUID();

            sb.setSubjectId(subjectId);
            sb.setCreatedTime(createTime);
            sbResult += subjectBankMapper.insert(sb);
            if (sbResult > 0) {
                tp.setTestPrimary(IdUtil.simpleUUID());
                tp.setTestId(testId);
                tp.setSubject(subjectId);
                tp.setCreatedTime(createTime);
                tpResult += testPaperMapper.insert(tp);
            }
        }

        if (sbResult == bankList.size() && tpResult == tpList.size())
            return HttpStatus.HTTP_OK;
        return HttpStatus.HTTP_INTERNAL_ERROR;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public int addRandomTest(List<TestPaper> tpList, String id) {

        // 将题目编号保存到试题集合中去
        List<String> idList;
        if (id.contains(",")) {
            String[] ids = id.split(",");
            idList = new ArrayList<>(Arrays.asList(ids));
        } else {
            idList = new ArrayList<>();
            idList.add(id);
        }

        // 当前试卷的试卷编号
        String testId = IdUtil.simpleUUID();
        // 统一创建时间
        Date createdTime = new Date();

        int index = 0;
        int result = 0;
        for (TestPaper tp : tpList) {
            tp.setTestPrimary(IdUtil.simpleUUID());
            tp.setTestId(testId);
            tp.setSubject(idList.get(index));
            tp.setCreatedTime(createdTime);
            result += testPaperMapper.insert(tp);
            index++;
        }

        return tpList.size() == result ? HttpStatus.HTTP_OK : HttpStatus.HTTP_INTERNAL_ERROR;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PageUtils<SubjectBank> queryAllSubjectByPage(Integer page, Integer limit, String subjectClazz) {
        PageHelper.startPage(page, limit);
        Example bankExample = new Example(SubjectBank.class);
        Example.Criteria bankCriteria = bankExample.createCriteria();
        bankCriteria.andEqualTo("subjectClazz", subjectClazz);
        List<SubjectBank> sbList = subjectBankMapper.selectByExample(bankExample);
        PageInfo<?> sbInfo = new PageInfo<>(sbList);
        PageUtils<SubjectBank> sbUtil = new PageUtils<>();
        sbUtil.setPage(page);
        sbUtil.setLimit(limit);
        sbUtil.setCount(sbInfo.getTotal());
        sbUtil.setData(sbList);
        return sbUtil;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PageUtils<DoTestPaperVO> queryTestPaperIsDone(Integer page, Integer limit, String stuId) {
        Map<String, Object> map = new HashMap<>();
        map.put("page", (page - 1) * limit);
        map.put("limit", limit);
        List<DoTestPaperVO> paperVOList = testPaperMapper.queryTestPaperIsDone(map);

        for (DoTestPaperVO tp : paperVOList) {
            Example ape = new Example(AnswerPaper.class);
            Example.Criteria apc = ape.createCriteria();
            apc.andEqualTo("testId", tp.getTestId());
            apc.andEqualTo("stuId", stuId);
            List<AnswerPaper> apl = answerPaperMapper.selectByExample(ape);
            if (apl.size() > 0)
                tp.setIsDone(YesOrNo.YES.type);
            else
                tp.setIsDone(YesOrNo.NO.type);
        }

        PageUtils<DoTestPaperVO> tpUtil = new PageUtils<>();
        tpUtil.setPage(page);
        tpUtil.setLimit(limit);
        tpUtil.setCount(testPaperMapper.selectAll().size());
        tpUtil.setData(paperVOList);
        return tpUtil;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<TestSubjectsVO> querySubjectByTestId(String id) {
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("testId", id);
        return testPaperMapper.querySubjectsByTestId(paramsMap);
    }
}
